
#pragma once
#include"Log.hpp"

#include <iostream>
#include <string>
#include <cstdio>
#include <set>
using namespace std;
using namespace LogModule;

const int line_size = 1024; // 一行

class Command
{
public:
    Command()
    {
        //// 课堂上， 只允许少量命令的执行， 限定一下命令的个数和范围
        _white_list.insert("ls");
        _white_list.insert("pwd");
        _white_list.insert("ls -l");
        _white_list.insert("ll");
        _white_list.insert("touch");
        _white_list.insert("who");
        _white_list.insert("whoami");
    }

    bool SafeCheck(const string& cmdstr)
    {
         auto iter = _white_list.find(cmdstr);
         return iter == _white_list.end() ? false : true;
    }

    // 给你一个命令字符串"ls -l" 让你执行,执行完,把结果返回
    string Execute(string cmdstr)
    {
        LOG(LogLevel::INFO) << "正在执行Execute....\n";
        if(!SafeCheck(cmdstr))  //不安全
         return string(cmdstr + "不支持");
        LOG(LogLevel::INFO) << "安全...\n";
        FILE *fp = ::popen(cmdstr.c_str(), "r");
        if (nullptr == fp)
        {
            return string("Failed");
        }

        char buffer[line_size];
        string result;
        while (true)
        {
            char *ret = fgets(buffer, sizeof(buffer), fp);
            if (ret == nullptr)
                break; // 读取有问题认为结束了
            result += ret;
        }
        pclose(fp);
        return result.empty() ? string("Done") : result; // 只要用户输入就有回响
    }

private:
    set<string> _white_list; // 白名单
};